using System;
using System.Net.Http;
using System.Text;
using System.Text.Json;
using System.Threading.Tasks;
using System.Collections.Generic;
using System.Diagnostics;
using System.Linq;
using System.IO;

namespace WpfApp1.Core
{
    public class SyncService : IDisposable
    {
        private readonly HttpClient _httpClient;
        private readonly string _baseUrl;
        private readonly string _deviceId;
        private readonly string _password;
        private bool _isConnected;
        private readonly AppSettings _settings;
        private bool _isDisposed;

        public event Action<string>? StatusChanged;
        public bool IsConnected => _isConnected;

        public SyncService()
        {
            _settings = LoadSettings();
            _baseUrl = _settings.ApiSettings.BaseUrl;
            _password = _settings.ApiSettings.Password;
            
            _httpClient = new HttpClient();
            _httpClient.DefaultRequestHeaders.Accept.Add(new System.Net.Http.Headers.MediaTypeWithQualityHeaderValue("application/json"));
            _httpClient.DefaultRequestHeaders.UserAgent.ParseAdd($"ClipboardSync/1.0.0 (Windows NT 10.0; Win64; x64)");

            // 简化设备标识为PC
            _deviceId = "PC";
            
            _isConnected = false;
            Debug.WriteLine($"同步服务已初始化，基础URL: {_baseUrl}");
        }

        public void Dispose()
        {
            if (!_isDisposed)
            {
                _isDisposed = true;
                _httpClient.Dispose();
            }
        }

        private void ThrowIfDisposed()
        {
            if (_isDisposed)
            {
                throw new ObjectDisposedException(nameof(SyncService));
            }
        }

        private void UpdateStatus(string status)
        {
            StatusChanged?.Invoke(status);
        }

        private AppSettings LoadSettings()
        {
            try
            {
                var configPath = Path.Combine(AppDomain.CurrentDomain.BaseDirectory, "appsettings.json");
                if (!File.Exists(configPath))
                {
                    throw new FileNotFoundException("配置文件不存在，请根据 appsettings.example.json 创建配置文件");
                }

                var jsonString = File.ReadAllText(configPath);
                var settings = JsonSerializer.Deserialize<AppSettings>(jsonString);
                if (settings == null)
                {
                    throw new Exception("配置文件格式错误");
                }

                if (string.IsNullOrEmpty(settings.ApiSettings.BaseUrl))
                {
                    throw new Exception("API 地址未配置");
                }

                if (string.IsNullOrEmpty(settings.ApiSettings.Password))
                {
                    throw new Exception("密码未配置");
                }

                return settings;
            }
            catch (Exception ex)
            {
                Debug.WriteLine($"加载配置文件失败: {ex}");
                throw new Exception($"加载配置文件失败: {ex.Message}");
            }
        }

        private HttpRequestMessage CreateRequest(HttpMethod method, string path)
        {
            ThrowIfDisposed();
            var request = new HttpRequestMessage(method, $"{_baseUrl}/api/{path}");
            request.Headers.Add("Cookie", $"auth={_password}");
            return request;
        }

        public async Task StartAsync()
        {
            ThrowIfDisposed();
            try
            {
                Debug.WriteLine($"开始连接服务器...");
                Debug.WriteLine($"基础URL: {_baseUrl}");
                Debug.WriteLine($"设备ID: {_deviceId}");
                UpdateStatus("正在连接...");

                // 测试连接
                var request = CreateRequest(HttpMethod.Get, "clipboard/history");
                Debug.WriteLine($"测试连接请求头: {string.Join(", ", request.Headers.Select(h => $"{h.Key}={string.Join(";", h.Value)}"))}");
                var response = await _httpClient.SendAsync(request);
                response.EnsureSuccessStatusCode();

                _isConnected = true;
                Debug.WriteLine("服务器连接成功");
                UpdateStatus("已连接");
            }
            catch (HttpRequestException ex)
            {
                _isConnected = false;
                var errorMessage = $"网络请求失败: {ex.Message}";
                Debug.WriteLine(errorMessage);
                UpdateStatus("连接失败");
                throw new Exception(errorMessage);
            }
            catch (Exception ex)
            {
                _isConnected = false;
                var errorMessage = $"连接失败: {ex.Message}";
                Debug.WriteLine(errorMessage);
                UpdateStatus("连接失败");
                throw;
            }
        }

        public async Task<bool> UploadContentAsync(string content)
        {
            ThrowIfDisposed();
            if (!_isConnected)
            {
                throw new Exception("未连接到服务器");
            }

            if (string.IsNullOrEmpty(content))
            {
                return false;
            }

            try
            {
                Debug.WriteLine($"准备上传内容: {content}");
                
                var request = CreateRequest(HttpMethod.Post, "clipboard/sync");
                
                // 使用 form-urlencoded 格式
                var formContent = new FormUrlEncodedContent(new[]
                {
                    new KeyValuePair<string, string>("content", content)
                });
                request.Content = formContent;
                
                Debug.WriteLine($"请求头: {string.Join(", ", request.Headers.Select(h => $"{h.Key}={string.Join(";", h.Value)}"))}");
                Debug.WriteLine($"Content头: {string.Join(", ", request.Content.Headers.Select(h => $"{h.Key}={string.Join(";", h.Value)}"))}");
                
                var response = await _httpClient.SendAsync(request);
                var responseContent = await response.Content.ReadAsStringAsync();
                Debug.WriteLine($"上传响应: HTTP {response.StatusCode}, 内容: {responseContent}");

                response.EnsureSuccessStatusCode();
                return true;
            }
            catch (Exception ex)
            {
                Debug.WriteLine($"上传内容失败: {ex}");
                throw new Exception($"上传失败: {ex.Message}");
            }
        }

        public async Task<List<ClipboardItem>> GetHistoryAsync()
        {
            ThrowIfDisposed();
            try
            {
                Debug.WriteLine("开始获取历史记录...");
                var request = CreateRequest(HttpMethod.Get, "clipboard/history");
                Debug.WriteLine($"请求URL: {request.RequestUri}");
                
                var response = await _httpClient.SendAsync(request);
                Debug.WriteLine($"历史记录响应状态: {response.StatusCode}");

                if (response.IsSuccessStatusCode)
                {
                    var content = await response.Content.ReadAsStringAsync();
                    Debug.WriteLine($"收到历史记录响应内容: {content}");
                    
                    if (string.IsNullOrEmpty(content))
                    {
                        Debug.WriteLine("响应内容为空");
                        return new List<ClipboardItem>();
                    }

                    try
                    {
                        var items = JsonSerializer.Deserialize<List<ClipboardItem>>(content);
                        Debug.WriteLine($"解析到 {items?.Count ?? 0} 条历史记录");
                        return items ?? new List<ClipboardItem>();
                    }
                    catch (JsonException ex)
                    {
                        Debug.WriteLine($"JSON解析失败: {ex.Message}");
                        Debug.WriteLine($"原始内容: {content}");
                        throw;
                    }
                }
                else if (response.StatusCode == System.Net.HttpStatusCode.NotFound)
                {
                    Debug.WriteLine("没有找到历史记录");
                    return new List<ClipboardItem>();
                }
                else
                {
                    var errorContent = await response.Content.ReadAsStringAsync();
                    Debug.WriteLine($"获取历史记录失败: HTTP {response.StatusCode}, 内容: {errorContent}");
                    throw new Exception($"获取历史记录失败: HTTP {response.StatusCode}");
                }
            }
            catch (Exception ex)
            {
                Debug.WriteLine($"获取历史记录失败: {ex}");
                throw new Exception($"获取历史记录失败: {ex.Message}");
            }
        }

        public async Task DeleteHistoryItemAsync(string itemId)
        {
            ThrowIfDisposed();
            if (!_isConnected)
            {
                throw new Exception("未连接到服务器");
            }

            try
            {
                var request = CreateRequest(HttpMethod.Delete, $"clipboard/delete/{itemId}");
                var response = await _httpClient.SendAsync(request);
                response.EnsureSuccessStatusCode();
            }
            catch (Exception ex)
            {
                Debug.WriteLine($"删除历史记录失败: {ex}");
                throw new Exception($"删除失败: {ex.Message}");
            }
        }

        public async Task ClearHistoryAsync()
        {
            ThrowIfDisposed();
            if (!_isConnected)
            {
                throw new Exception("未连接到服务器");
            }

            try
            {
                var request = CreateRequest(HttpMethod.Delete, "clipboard/clear");
                var response = await _httpClient.SendAsync(request);
                response.EnsureSuccessStatusCode();
            }
            catch (Exception ex)
            {
                Debug.WriteLine($"清空历史记录失败: {ex}");
                throw new Exception($"清空失败: {ex.Message}");
            }
        }
    }
} 